package io.github.yotta.notice.common.provider;

import io.github.yotta.notice.common.dto.NoticeToken;
import io.github.yotta.notice.common.exception.NoticeException;
import io.github.yotta.notice.common.exception.TokenNotFindException;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.text.MessageFormat;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author yotta
 * @date 2023/4/30 14:17
 */
@Slf4j
public abstract class MapNoticeTokenProvider<T extends NoticeToken> implements NoticeTokenProvider<T> {

    protected final ConcurrentHashMap<String, T> tokenMap = new ConcurrentHashMap<>();

    @Setter
    private T defaultToken;

    protected MapNoticeTokenProvider(T defaultToken) {
        this.defaultToken = defaultToken;
    }

    @Override
    public T findToken(String tenantId) throws TokenNotFindException {
        if (Objects.isNull(tenantId)) {
            return defaultToken();
        }
        final T t = this.tokenMap.get(tenantId);
        final T token = Objects.nonNull(t) ? t : defaultToken();
        if (Objects.isNull(token)) {
            throw new TokenNotFindException(MessageFormat.format("tenant [{0}] not find token info", tenantId));
        }
        return token;
    }

    @Override
    public void registerToken(String tenantId, T token) {
        try {
            tokenMap.put(tenantId, token);
        } catch (Exception e) {
            log.error("register token fail, tenantId={}, token={}, cause={}", tenantId, token, e.getMessage(), e);
            throw new NoticeException("register.token.fail");
        }
    }

    @Override
    public T defaultToken() throws TokenNotFindException {
        if (Objects.isNull(defaultToken)) {
            throw new TokenNotFindException("default token not find");
        }
        return defaultToken;
    }
}
